/* 
 * PasswordHelper.java created at: 2005-3-7 10:09:54 by elvis
 * $Id: PasswordHelper.java,v 1.1 2006/06/08 02:49:57 fenghm Exp $ 
 */

package net.bingosoft.common.util;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.mail.internet.MimeUtility;


import net.bingosoft.common.config.Config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * @author elvis
 */
public final class PasswordHelper {
    
    private static final Log log = LogFactory.getLog(PasswordHelper.class);
    
    private static final String ALGORITHM_KEY = "digest.algorithm";
    
    //default length of password string to be generated.
    private static final int DEFAULT_PASSWORD_LENGTH = 6;
    
    //缺省加密算法
    private static final String DEFUALT_ALGORITHM = "MD5";
    
    private static final String BYTES_ENCODING = Config.getString("PASSWORD_ENCODING","ISO-8859-1");
    
    //密码字符
    private static final char[] PASSWORD_CHARS = {
            '1','2','3','4','5','6','7','8',
            '9','0',
            'a','b','c','d','e','f','g','h',
            'i','j','k','l','m',
            'n','o','p','q','r','s','t','u',
            'v','w','x','y','z'
    };
    
    private int passwordLength = DEFAULT_PASSWORD_LENGTH;
    
    public PasswordHelper(){}

    /**
     * @return Returns the passwordLength.
     */
    public int getPasswordLength() {
        return passwordLength;
    }
    /**
     * @param passwordLength The passwordLength to set.
     */
    public void setPasswordLength(int passwordLength) {
        this.passwordLength = passwordLength;
    }
    
    /**
     * 产生随机密码
     * @return 密码
     */
    public String genernatePassword(){
        StringBuffer sb = new StringBuffer(passwordLength);
        int passwordCharsLength = PASSWORD_CHARS.length;

        SecureRandom random = new SecureRandom();
        for(int i = 0; i < passwordLength; i++){
            sb.append(PASSWORD_CHARS[random.nextInt(passwordCharsLength)]);
        }

        return sb.toString();
    }
    
    /**
     * 对密码进行加密
     * @param password 明文密码
     * @return 加密后密码
     */
    public String encryptPassword(String password){
        String digestPassword = "";
        if(null != password){
            MessageDigest messageDigest;
            byte[] digestMsg = null;
            //利用加密算法进行加密
            try{
                try{
                    messageDigest = MessageDigest.getInstance(getAlgorithm());
                }catch(NoSuchAlgorithmException ne){
                    if(log.isInfoEnabled()){
                        log.info("No Such Algorithm:" + getAlgorithm(),ne);
                    }
                    messageDigest = MessageDigest.getInstance(DEFUALT_ALGORITHM);
                }
                digestMsg = messageDigest.digest(password.getBytes(BYTES_ENCODING));
            }catch(Exception e){
                log.error(e);
            }
            //把加密结果进行base64编码
            if(null != digestMsg){
                try{
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
                    OutputStream encodedStream = MimeUtility.encode(bos, "base64");
                    encodedStream.write(digestMsg);
                    digestPassword = bos.toString(BYTES_ENCODING);
                }catch(Exception e){
                    log.error(e);
                }
            }
        }
        return digestPassword;
    }
    
    /**
     * 比较某个密码与加密密码是否相等
     * @param encryptedPassword 加密密码
     * @param password 要比较的密码
     * @return 相同返回true,否则返回false
     */
    public boolean verifyPassword(String encryptedPassword,String password){
        String digestPassword = encryptPassword(password);
        return digestPassword.equals(encryptedPassword);
    }
    
    /**
     * 读取加密算法，默认为MD5
     * @return 加密算法
     */
    private static String getAlgorithm(){
        String algorithm = Config.getString(ALGORITHM_KEY,"MD5");
        if(null == algorithm || "".equals(algorithm.trim())){
            algorithm = DEFUALT_ALGORITHM;
        }
        return algorithm;
    }
}
